package com.ponxu.mb.db;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;

import com.ponxu.db.DBException;
import com.ponxu.log.Log;
import com.ponxu.log.LogFactory;
import com.ponxu.mb.Global;
import com.ponxu.mb.exception.BlogException;

/**
 * Blog 连接/连接池管理
 * 
 * @author xwz
 * 
 */
public class ConnectionManager {
	private static final Log LOG = LogFactory.getLog();
	private static final ThreadLocal<Connection> threadConnection = new ThreadLocal<Connection>();

	private static boolean inited = false;

	private static String driver;
	private static String host;
	private static String name;
	private static String username;
	private static String password;
	private static String mysqlurl;

	public synchronized static void init() {
		if (inited)
			return;

		driver = Global.read("DB_DRIVER_CLASS");
		host = Global.read("DB_HOST");
		name = Global.read("DB_NAME");
		username = Global.read("DB_USERNAME");
		password = Global.read("DB_PASSWORD");
		mysqlurl = "jdbc:mysql://" + host + ":3306/" + name;

		try {
			Class.forName(driver);

			// 初始化连接池 begin------------------------

			Connection conn = getConnection();
			DatabaseMetaData mdm = conn.getMetaData();
			LOG.info("Connected to " + mdm.getDatabaseProductName() + " "
					+ mdm.getDatabaseProductVersion());
			conn.close();

			// 初始化连接池 end-------------------------

		} catch (ClassNotFoundException e) {
			throw new BlogException("DB_DRIVER_CLASS Error! " + driver, e);
		} catch (SQLException e) {
			throw new BlogException("Cann't Connect To Database Host! "
					+ mysqlurl, e);
		}

		inited = true;
	}

	public static void destroy() {
		if (!inited)
			return;

		// 清理操作
	}

	// 直接从连接池取
	private static Connection getConnection() {
		try {
			Connection conn = DriverManager.getConnection(mysqlurl, username,
					password);
			conn.setAutoCommit(false);
			return conn;
		} catch (SQLException e) {
			LOG.warn("Get Connection Failed!");
			throw new DBException(e);
		}
	}

	// 先寻找线程中连接, 若无, 再从连接池取
	public static Connection get() {
		Connection conn = threadConnection.get();
		if (conn == null) {
			conn = getConnection();
			threadConnection.set(conn);
		}
		return conn;
	}

	public static void release() {
		release(threadConnection.get());
		threadConnection.set(null); // 此句必须, 容器使用线程池, 导致threadConnection会重复利用
	}

	public static void commit() {
		commit(threadConnection.get());
	}

	public static void rollback() {
		rollback(threadConnection.get());
	}

	public static void release(Connection conn) {
		try {
			if (conn != null) {
				conn.close();
			}
		} catch (SQLException e) {
			LOG.warn("JDBC Close Connection Failed!");
			throw new DBException(e);
		}
	}

	public static void commit(Connection conn) {
		try {
			if (conn != null) {
				conn.commit();
			}
		} catch (SQLException e) {
			LOG.warn("JDBC Commit Failed!");
			throw new DBException(e);
		}
	}

	public static void rollback(Connection conn) {
		try {
			if (conn != null) {
				conn.rollback();
			}
		} catch (SQLException e) {
			LOG.warn("JDBC Rollback Failed!");
			throw new DBException(e);
		}
	}
}
